<template>
    <div class="rich-search">
        <div class="has-select">
            <div class="label">已选条件</div>
            <div class="tags-content">
                <template v-if="hasSelect.length">
                    <div
                        class="tags"
                        v-for="(item, index) in hasSelect"
                        :key="index"
                    >
                        <span>{{ item.label }}</span>
                        <i
                            class="iconfont icon-close"
                            @click="
                                onSelectDelTag(
                                    item.code,
                                    item.value,
                                    item.label
                                )
                            "
                        />
                    </div>
                    <div class="del-all" @click="delAllTag">
                        <i class="iconfont icon-delete" />
                        <span>清空</span>
                    </div>
                </template>
                <div class="none" v-else>无</div>
            </div>
        </div>
        <div class="select-content">
            <template v-for="(item, index) in props.data" :key="index">
                <div
                    class="item-content"
                    :class="{ 'border-line': props.borderList.includes(index) }"
                    v-show="index <= props.len || showMore"
                    :style="getItemWidth(item.grid)"
                >
                    <div
                        class="label"
                        :class="{
                            'select-label':
                                item.type === 'tree-select' ||
                                item.type === 'select' ||
                                item.type === 'date' ||
                                item.type === 'date-range',
                        }"
                    >
                        <n-ellipsis style="max-width: 70px">
                            {{ item.name }}
                        </n-ellipsis>
                    </div>
                    <n-tree-select
                        v-if="item.type === 'tree-select'"
                        :options="item.options"
                        checkable
                        filterable
                        clearable
                        :placeholder="item.placeholder || '请选择'"
                        :key-field="item.keyField || 'value'"
                        :label-field="item.labelField || 'label'"
                        class="select-input"
                        v-model:value="seletVals[item.code].value"
                        @update:value="
                            (val, option) =>
                                selectChange(item.code, val, option)
                        "
                    />
                    <n-select
                        v-else-if="item.type === 'select'"
                        v-model:value="seletVals[item.code].value"
                        clearable
                        filterable
                        :placeholder="item.placeholder || '请选择'"
                        :options="item.options"
                        class="select-input"
                        @update:value="
                            (val, option) =>
                                selectChange(item.code, val, option)
                        "
                    />
                    <n-date-picker
                        v-else-if="item.type === 'date'"
                        v-model:value="seletVals[item.code].value"
                        type="date"
                        class="select-input"
                        style="height: 30px"
                        :placeholder="item.placeholder"
                        close-on-select
                        clearable
                        @update:value="(val) => dateChange(item.code, val)"
                        value-format="yyyy-MM-dd"
                    />
                    <n-date-picker
                        v-else-if="item.type === 'date-range'"
                        v-model:value="seletVals[item.code].value"
                        type="daterange"
                        class="select-input"
                        style="height: 30px"
                        close-on-select
                        :actions="null"
                        clearable
                        @update:value="(val) => dateRangeChange(item.code, val)"
                        value-format="yyyy-MM-dd"
                    />
                    <Toggle
                        v-else-if="item.type === 'toggle-select'"
                        :data="item.children"
                        :select="seletVals"
                        @selectTag="onSelectTag"
                        @selectTagAll="onSelectTagAll"
                    />
                    <TagsSelect
                        v-else-if="item.type === 'tags-select'"
                        :data="item.children"
                        :select="seletVals[item.code].value"
                        @selectTag="
                            (pCode, code, name) =>
                                onTagsSelect(item.code, pCode, code, name)
                        "
                        @selectTagAll="
                            (codes, labels) =>
                                onTagsSelectAll(item.code, codes, labels)
                        "
                    />
                    <div class="tags-content" v-else>
                        <div
                            class="tags"
                            @click="onSelectTagAll(item.code, item.multiple)"
                            :class="{
                                active: getIsAllSelect(
                                    item.code,
                                    item.multiple
                                ),
                            }"
                        >
                            全部
                        </div>
                        <div
                            class="tags"
                            :class="{
                                active: getIsSelect(
                                    item.code,
                                    _item.value,
                                    item.multiple
                                ),
                            }"
                            v-for="(_item, _index) in item.options"
                            :key="_index"
                            @click="
                                onSelectTag(
                                    _item.value,
                                    item.code,
                                    _item.label,
                                    item.multiple
                                )
                            "
                        >
                            {{ _item.label }}
                        </div>
                    </div>
                </div>
            </template>
        </div>
        <div
            class="show-more"
            v-if="props.data.length > props.len + 1"
            :class="{ show: showMore }"
        >
            <span @click="showMore = !showMore"
                >{{ !showMore ? "展开更多" : "收起更多" }}
            </span>
            <i class="iconfont icon-down" />
        </div>
    </div>
</template>
<script setup>
import { computed, watch, ref, inject } from "vue";
import Toggle from "./Toggle.vue";
import TagsSelect from "./TagsSelect.vue";

const global = inject("global");

let dateTypeList = ["date", "date-range"];

const props = defineProps({
    data: {
        type: Array,
        default: () => [],
    },
    default: {
        type: Object,
        default: () => {},
    },
    len: {
        type: Number,
        default: () => 2,
    },
    borderList: {
        type: Array,
        default: [],
    },
    //初始化是否触发change事件
    immediate: {
        type: Boolean,
        default: () => false,
    },
});

const showMore = ref(false);
const isFirst = ref(true);

//宽度
const getItemWidth = (grid) => {
    if (grid === 2) return "width: 50%;";
    if (grid === 3) return "width: 33.333333%;";
};

//获取匹配的label
const getArrayLabel = (val, arr, _label = "") => {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i].value === val) {
            _label = arr[i].label;
            break;
        }
        if (arr[i].children && arr[i].children.length) {
            _label = getArrayLabel(val, arr[i].children, _label);
        }
    }
    return _label;
};

const emits = defineEmits(["change"]);

// 可选项
const seletVals = ref(null);

const getDataObj = (arr, obj = {}) => {
    arr.length &&
        arr.map((item) => {
            let _defaultValue = null,
                _defaultLabel = null;
            if (item.type !== "tags-select") {
                if (item.children) {
                    getDataObj(item.children, obj);
                }
                if (!item.code) return;
                _defaultValue =
                    props.default && props.default[item.code]
                        ? props.default[item.code]
                        : null;
                let isArray = Array.isArray(_defaultValue);
                if (isArray) {
                    let _list = [];
                    item.options &&
                        item.options.map((_item) => {
                            if (_defaultValue.includes(_item.value))
                                _list.push(_item.label);
                        });
                    _defaultLabel = _list;
                } else {
                    let _label =
                        _defaultValue &&
                        getArrayLabel(_defaultValue, item.options);
                    _defaultLabel = _label;
                }
            }
            if (item.type === "date") {
                obj[item.code] = {
                    name: item.name,
                    type: item.type,
                    keyField: item.keyField,
                    labelField: item.labelField,
                    label: item.multiple
                        ? _defaultLabel || []
                        : _defaultLabel || null,
                    value: item.multiple
                        ? _defaultValue || []
                        : _defaultValue || null,
                };
            } else {
                obj[item.code] = {
                    name: item.name,
                    type: item.type,
                    keyField: item.keyField,
                    labelField: item.labelField,
                    label: item.multiple
                        ? _defaultLabel || []
                        : _defaultLabel || null,
                    value: item.multiple
                        ? _defaultValue || []
                        : _defaultValue || null,
                };
            }
        });
    return obj;
};

watch(
    () => props.data,
    (newVal) => {
        let _obj = getDataObj(newVal);
        seletVals.value = _obj;
    },
    {
        deep: true,
        immediate: props.immediate || true,
    }
);

watch(
    seletVals,
    (newVal) => {
        if (!isFirst.value || props.immediate) emits("change", newVal);
        isFirst.value = false;
    },
    {
        deep: true,
        immediate: props.immediate || true,
    }
);

//已选条件
const hasSelect = computed(() => {
    let _list = [];
    for (let key in seletVals.value) {
        const _labelList = seletVals.value[key].label
            ? seletVals.value[key].label
            : null;
        const _valuelList = seletVals.value[key].value
            ? seletVals.value[key].value
            : null;
        if (_labelList) {
            if (Array.isArray(_labelList)) {
                _labelList.map((item, index) => {
                    _list.push({
                        code: key,
                        label: item,
                        value: _valuelList[index],
                    });
                });
            } else {
                _list.push({
                    code: key,
                    label: _labelList,
                    value: _valuelList,
                });
            }
        }
    }
    return _list;
});

//点击选项
const onSelectTag = (val, code, label, multiple) => {
    let _res = false;
    //判断是否已选中
    hasSelect.value.map((item) => {
        if (item.value === val && item.code === code) {
            _res = true;
        }
    });
    let _value = seletVals.value[code].value;
    let _label = seletVals.value[code].label;
    if (!_res) {
        seletVals.value[code] = {
            ...seletVals.value[code],
            value: multiple ? [..._value, val] : val,
            label: multiple ? [..._label, label] : label,
        };
    } else {
        seletVals.value[code] = {
            ...seletVals.value[code],
            value: multiple ? _value.filter((item) => item !== val) : null,
            label: multiple ? _label.filter((item) => item !== label) : null,
        };
    }
};

//点击选项的全部
const onSelectTagAll = (code, multiple) => {
    seletVals.value[code] = {
        value: multiple ? [] : null,
        label: multiple ? [] : null,
    };
};

//点击人员标签
const onTagsSelect = (_code, pCode, code, name) => {
    let _res = false;
    //判断是否已选中
    hasSelect.value.map((item) => {
        if (item.label === name && item.value === code) {
            _res = true;
        }
    });
    let _value = seletVals.value[_code].value;
    let _label = seletVals.value[_code].label;
    if (!_res) {
        seletVals.value[_code] = {
            ...seletVals.value[_code],
            value: [..._value, code],
            label: [..._label, name],
        };
    } else {
        seletVals.value[_code] = {
            ...seletVals.value[_code],
            value: _value.filter((item) => item !== code),
            label: _label.filter((item) => item !== name),
        };
    }
};

//点击人员标签全部
const onTagsSelectAll = (_code, codes, names) => {
    let _value = seletVals.value[_code].value;
    let _label = seletVals.value[_code].label;
    seletVals.value[_code] = {
        value: _value.filter((item) => !codes.includes(item)),
        label: _label.filter((item) => !names.includes(item)),
    };
};

//判断选项是否选中
const getIsSelect = (code, val, multiple) => {
    const _values = seletVals.value[code].value || "";
    if (multiple && _values && _values.includes(val)) return true;
    if (_values && _values === val) return true;
    return false;
};

//判断全部是否选中
const getIsAllSelect = (code, multiple) => {
    const _values = seletVals.value[code].value || "";
    if (multiple && _values && !_values.length) return true;
    if (!multiple && !_values) return true;
    return false;
};

//点击已选条件的删除
const onSelectDelTag = (code, val, label) => {
    let _res = false;
    let _type = seletVals.value[code].type || "";
    if (dateTypeList.includes(_type)) _res = true;
    let _value = seletVals.value[code].value;
    let _label = seletVals.value[code].label;
    const _isMultiple = Array.isArray(_value);
    if (_type === "date-range") {
        seletVals.value[code] = {
            ...seletVals.value[code],
            value: null,
            label: [],
        };
    } else if (_type === "date") {
        seletVals.value[code] = {
            ...seletVals.value[code],
            value: null,
            label: "",
        };
    } else {
        seletVals.value[code] = {
            ...seletVals.value[code],
            value:
                _isMultiple && !_res
                    ? _value.filter((item) => item !== val)
                    : null,
            label:
                _isMultiple && !_res
                    ? _label.filter((item) => item !== label)
                    : null,
        };
    }
};

//点击清空
const delAllTag = () => {
    let _obj = {};
    for (let key in seletVals.value) {
        const _isMultiple = Array.isArray(seletVals.value[key].value);
        let _res = false;
        let _type = seletVals.value[key].type || "";
        if (dateTypeList.includes(_type)) _res = true;
        if (_type === "date-range") {
            _obj[key] = {
                ...seletVals.value[key],
                label: [],
                value: null,
            };
        } else if (_type === "date") {
            _obj[key] = {
                ...seletVals.value[key],
                label: "",
                value: null,
            };
        } else {
            _obj[key] = {
                ...seletVals.value[key],
                label: _isMultiple && !_res ? [] : null,
                value: _isMultiple && !_res ? [] : null,
            };
        }
    }
    seletVals.value = _obj;
};

//树选择、下拉选择改变
const selectChange = (code, value, option) => {
    seletVals.value[code] = {
        ...seletVals.value[code],
        value: value || null,
        label:
            (option && option.label) ||
            (option && option[seletVals.value[code].labelField]) ||
            null,
    };
};

//时间改变
const dateChange = (code, value) => {
    seletVals.value[code].label = value
        ? global.$dayjs(value).format("YYYY-MM-DD")
        : null;
};

//时间范围改变
const dateRangeChange = (code, value) => {
    let _start = value ? global.$dayjs(value[0]).format("YYYY-MM-DD") : "";
    let _end = value ? global.$dayjs(value[1]).format("YYYY-MM-DD") : "";
    seletVals.value[code].label = value ? `${_start} ~ ${_end}` : null;
};

const getPopupContainer = (trigger) => {
    return trigger.parentNode;
};

//样例数据
// const domeData = [
//     {
//         code: "tags",
//         name: "人员标签",
//         type: "tags-select",
//         multiple: true,
//         children: [
//             {
//                 code: "basic_class",
//                 name: "基础标签",
//                 children: [
//                     {
//                         name: "人口标签",
//                         code: "population",
//                         children: [
//                             {
//                                 code: "hbck",
//                                 name: "湖北常口标签",
//                             },
//                             {
//                                 code: "hblk",
//                                 name: "湖北流口标签",
//                             },
//                         ],
//                     },
//                     {
//                         name: "财产标签",
//                         code: "property",
//                         children: [
//                             {
//                                 code: "jdc",
//                                 name: "机动车标签",
//                             },
//                         ],
//                     },
//                 ],
//             },
//             {
//                 code: "attribute",
//                 name: "属性标签",
//                 children: [
//                     {
//                         name: "证照标签",
//                         code: "license",
//                         children: [
//                             {
//                                 code: "jsz",
//                                 name: "驾驶证标签",
//                             },
//                         ],
//                     },
//                 ],
//             },
//         ],
//     },
//     {
//         code: "all",
//         name: "全部",
//         type: "toggle-select",
//         multiple: true,
//         children: [
//             {
//                 code: "fwcs",
//                 name: "服务场所",
//                 multiple: true,
//                 options: [
//                     {
//                         value: "小米",
//                         label: "小米",
//                     },
//                     {
//                         value: "华为",
//                         label: "华为",
//                     },
//                 ],
//             },
//             {
//                 code: "fwcs2",
//                 name: "服务场所2",
//                 options: [
//                     {
//                         value: "11",
//                         label: "11",
//                     },
//                 ],
//             },
//         ],
//     },
//     {
//         code: "gkzt",
//         name: "管控状态",
//         multiple: true,
//         options: [
//             { value: "0", label: "管控中" },
//             { value: "1", label: "注销" },
//             { value: "2", label: "短期离开" },
//             { value: "3", label: "失轨" },
//         ],
//     },
//     {
//         code: "beginTime1",
//         name: "时间xx",
//         type: "date",
//         grid: 1,
//     },
//     {
//         code: "beginTime",
//         name: "下发时间",
//         type: "date-range",
//         multiple: true,
//         grid: 1,
//     },
// ];
</script>
<style lang="less" scoped>
.rich-search {
    padding: 24px 20px 14px;
    .has-select {
        display: flex;
        align-items: flex-start;
        margin-bottom: 2px;
        padding-bottom: 2px;
        // border-bottom: 1px dashed #ddd;
        .label {
            width: 70px;
            min-width: 70px;
            text-align: right;
            color: var(--text-color-base-2);
            margin-right: 20px;
            position: relative;
            line-height: 26px;

            &::after {
                content: "：";
                position: absolute;
                right: -16px;
                top: 50%;
                height: 24px;
                line-height: 24px;
                transform: translateY(-50%);
            }
        }
        .tags-content {
            display: flex;
            flex-wrap: wrap;
            .tags {
                line-height: 26px;
                height: 26px;
                margin-right: 10px;
                margin-bottom: 8px;
                padding: 0 5px 0 8px;
                border-radius: 2px;
                color: var(--text-color-base);
                transition: all 0.2s ease-in-out;
                display: flex;
                align-items: center;
                white-space: nowrap;
                border: 1px solid var(--primary-color);
                box-sizing: border-box;
                svg {
                    width: 12px;
                    margin-left: 6px;
                    cursor: pointer;
                    transition: all 0.2s ease-in-out;
                    color: #777;
                    &:hover {
                        color: var(--primary-color);
                    }
                }
            }
            .none {
                color: #9b9b9b;
                line-height: 26px;
                margin-bottom: 8px;
            }
            .del-all {
                height: 26px;
                display: flex;
                align-items: center;
                white-space: nowrap;
                cursor: pointer;
                transition: all 0.2s ease-in-out;
                color: var(--text-color-base-2);
                &:hover {
                    color: var(--primary-color);
                }
                svg {
                    width: 16px;
                    margin-right: 2px;
                }
            }
        }
    }
    .select-content {
        display: flex;
        flex-wrap: wrap;
    }
    .item-content {
        width: 100%;
        display: flex;
        align-items: flex-start;
        margin-bottom: 10px;
        padding-bottom: 2px;
        position: relative;
        &:last-child {
            margin-bottom: 0;
        }
        &.border-line {
            &::after {
                content: "";
                position: absolute;
                border-bottom: 1px dashed rgba(155, 155, 155, 0.2);
                left: -20px;
                right: -20px;
                bottom: 0;
                height: 1px;
            }
        }
        // border-bottom: 1px dashed #ddd;
        .label {
            width: 70px;
            min-width: 70px;
            text-align: right;
            color: var(--text-color-base-2);
            margin-right: 20px;
            position: relative;
            line-height: 24px;
            &.select-label {
                line-height: 30px;
            }
            &::after {
                content: "：";
                position: absolute;
                right: -16px;
                top: 50%;
                height: 24px;
                line-height: 24px;
                transform: translateY(-50%);
            }
        }
        .tags-content {
            display: flex;
            flex-wrap: wrap;
            position: sticky;
            .tags {
                line-height: 24px;
                height: 24px;
                margin-right: 10px;
                margin-bottom: 8px;
                padding: 0 10px;
                border-radius: 2px;
                cursor: pointer;
                color: var(--text-color-base);
                transition: all 0.2s ease-in-out;
                &:hover {
                    background: var(--primary-color);
                    color: #fff;
                }
                &.active {
                    background: var(--primary-color);
                    color: #fff;
                }
            }
        }
    }
    .select-input {
        width: 350px !important;
        margin-bottom: 10px;
        :deep(.n-input-wrapper) {
            height: 30px;
            .n-input__input-el {
                height: 30px;
                line-height: 30px;
            }
        }
    }
    .show-more {
        display: flex;
        align-items: center;
        justify-content: center;
        color: #9b9b9b;
        span {
            cursor: pointer;
        }
        &.show {
            svg {
                transform: rotate(180deg);
            }
        }
        svg {
            transition: all 0.2s ease-in-out;
            width: 14px;
            margin-left: 4px;
        }
    }
}
:deep(.n-base-selection) {
    min-height: 30px;
    line-height: 30px;
    .n-base-selection-label {
        height: 30px;
    }
}
:deep(.date-input) {
    padding-left: 16px;
    .ant-picker-range-separator {
        padding-right: 16px;
    }
}
</style>
